package com.hroze.util;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.quartz.CronExpression;
import org.quartz.CronTrigger;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.impl.StdSchedulerFactory;

import com.hroze.util.web.Prop;

/**
 * @author ahoo 
 * 调度工具类
 *
 */
public class JobManager {
	private Prop config;
	private SchedulerFactory sf;
	private static JobManager m;
	private List<Map<String, String>> list;
	private Scheduler sc;
	public static final String group = "root";
	private Logger log;

	/**
	 * 生成一个调度类
	 */
	private JobManager() {
		// anyone can't try to new it
		config = new Prop(JobManager.class);
		log = Logger.getLogger("Quart");
		sf = new StdSchedulerFactory();
		try {
			sc = sf.getScheduler();
			sc.start();
		} catch (SchedulerException e) {
			log.error("Quart启动失败",e);
		}
	}

	
	/**
	 * 查找调度配置参数
	 * @param name
	 * @return
	 */
	public Map<String, String> find(String name) {
		Map<String, String> m = null;
		if (list == null) {
			return null;
		}
		for (Map<String, String> o : list) {
			if (name.equals(o.get("name"))) {
				m = o;
			}
		}
		return m;
	}

	/**
	 * 保存配置文件
	 */
	public void save() {
		if (list != null) {
			String json = JsonUtil.objectToJson(list);
			config.set("list", json);
		} else {
			config.set("list", "[]");
		}
		config.save();
	}

	
	/**
	 * 增加新的计划任务
	 * @param name 任务名
	 * @param group 任务组
	 * @param clazz 任务类
	 * @param el   控制表达式
	 * @return
	 */
	public boolean add(String name, String group, Class clazz, String el) {
		try {
			CronTrigger cronTrigger = new CronTrigger();
			cronTrigger.setName(name);
			JobDetail jobDetail = new JobDetail(name, group, clazz);
			CronExpression cexp = new CronExpression(el);
			cronTrigger.setCronExpression(cexp);
			sc.scheduleJob(jobDetail, cronTrigger);
			Map<String, String> m = new HashMap<String, String>();
			m.put("name", name);
			m.put("group", group);
			m.put("el", el);
			m.put("clazz", clazz.getCanonicalName());
			if (list == null) {
				list = new ArrayList();
			}
			list.add(m);
			this.save();
		} catch (SchedulerException e) {
			log.error("计划任务失败�����ƻ�����ʧ��", e);
			return false;
		} catch (ParseException e) {
			log.error("解析表达式错误�����ƻ�����ʧ��", e);
			return false;
		} catch (IllegalArgumentException e) {
			log.error("�������ʵ��job�ӿ参数状态错误", e);
		}
		return true;
	}

	/**
	 * 使用默认的组增加任务
	 * @param name
	 * @param clazz
	 * @param el
	 * @return
	 */
	public boolean add(String name, Class clazz, String el) {
		return this.add(name, group, clazz, el);
	}

	/**
	 * 使用名字删除调度（使用默认组）
	 * @param name 调度名字
	 * @return
	 */
	public boolean remove(String name) {
		return this.remove(name, group);
	}

	/**
	 * 删除调度任务
	 * @param name 调度名字
	 * @param group 调度组
	 * @return
	 */
	public boolean remove(String name, String group) {
		try {
			Map m = this.find(name);
			if (m != null) {
				sc.deleteJob(name, group);
				list.remove(m);
				this.save();
			}
			return true;
		} catch (SchedulerException e) {
			log.error("删除调度任务失败", e);
			return false;
		}
	}

	public void stop() {
		try {
			sc.shutdown();
		} catch (SchedulerException e) {
			log.error("停止调度任务失败", e);
		}
	}

	/**
	 * 载入配置文件中计划任务
	 */
	public void load() {
		String listStr = config.get("list");
		if (StringUtils.isNotBlank(listStr)) {
			List tempList = (List<Map<String, String>>) JsonUtil
					.jsonToObj(listStr);
			if (tempList != null) {
				Iterator<Map<String, String>> it = tempList.iterator();
				while (it.hasNext()) {
					try {
						Map<String, String> o = it.next();
						this.add(o.get("name"), o.get("group") == null ? group
								: o.get("group"),
								Class.forName(o.get("clazz")), o.get("el"));
					} catch (ClassNotFoundException e) {
						log.error("无法找到调度配置文件中指定的类", e);
					}
				}
			}
		}
	}

	/**
	 * 获得调度管理器实例
	 * @return 返回唯一实例
	 */
	public static JobManager getManager() {
		if (m == null) {
			m = new JobManager();
		}
		return m;
	}

}
